#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <time.h>


void *philosopher(void *arg);
int takechopstick(int number);
void putchopstick(int number);

int num_threads;
pthread_mutex_t *mutex;

int main(int argc, char *argv[])
{
	num_threads=atoi(argv[1]);
	mutex=(pthread_mutex_t *)malloc(num_threads*sizeof(pthread_mutex_t));
    if(argc == 2)
    {
        pthread_t threads[num_threads];
        int mutex_init,mutex_destroy;
        for(int i=0;i<num_threads;i++)
        {
        	pthread_create(&threads[i],NULL,(void*)philosopher,(void*)(intptr_t)i);
        	if((mutex_init=pthread_mutex_init(&mutex[i],NULL))!=0)
        	{
        		perror((char *)(intptr_t)mutex_init);
        	}
        }
        for(int i=0;i<num_threads;i++)
        {
            pthread_join(threads[i],NULL);
        }
        for(int i=0;i<num_threads;i++)
        {
            if((mutex_destroy=pthread_mutex_destroy(&mutex[i]))!=0)
            {
                 perror((char *)(intptr_t)mutex_destroy);
            }
        }
    }
    else
    {
    	printf("usage: philosopher [number]\n");
    }
    return 0;
}

void *philosopher(void *arg)
{
	int number=(intptr_t)(int*)arg;
	while(1)
	{
//		srand((unsigned)time(NULL));
		printf("philosopher %d is thinking\n", number);
//		sleep(rand()%10);
		sleep(2);
		if(takechopstick(number)!=0)
		{
			continue;
		}
		if(takechopstick((number+1)%num_threads)!=0)
		{
			putchopstick(number);
			continue;
		}
		printf("philosopher %d is eating\n", number);
//		sleep(rand()%10);
		sleep(2);
		putchopstick(number);
		putchopstick((number+1)%num_threads);
	}
}

int takechopstick(int number)
{
	int mutex_trylock;
    mutex_trylock=pthread_mutex_trylock(&mutex[number]);
    return mutex_trylock;
}

void putchopstick(int number)
{
	int mutex_unlock;
	if((mutex_unlock=pthread_mutex_unlock(&mutex[number]))!=0)
	{
	    perror((char *)(intptr_t)mutex_unlock);
	}
}


